<?php
namespace app\protocol;

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use think\App;

class Server
{
    protected $worker;
    protected $router;
    protected $app;


    public function __construct(App $app, $config = [])
    {
        $this->app = $app;
        $this->router = new Router($app);
        $this->initializeServer($config);
    }

    protected function initializeServer($config): void
    {
        $host = $config['host'] ?? '0.0.0.0';
        $port = $config['port'] ?? 8765;

        $this->worker = new Worker("text://{$host}:{$port}");
        $this->worker->count = $config['worker_count'] ?? 1;
        $this->worker->name = 'thinkphp-text-protocol';

        // 设置事件回调
        $this->worker->onConnect = [$this, 'onConnect'];
        $this->worker->onMessage = [$this, 'onMessage'];
        $this->worker->onClose = [$this, 'onClose'];
        $this->worker->onError = [$this, 'onError'];
    }

    public function onConnect(TcpConnection $connection): void
    {
        $connection->send("欢迎使用 ThinkPHP 8.0 文本协议服务器\r\n");
        $connection->send("连接时间: " . date('Y-m-d H:i:s') . "\r\n");
        $connection->send("输入 'help' 查看可用命令\r\n\r\n");
    }

    public function onMessage(TcpConnection $connection, $data): void
    {
        $data = trim($data);

        $data = preg_replace('/\s+/', ' ', $data);

        // 3. (可选但推荐) 移除其他可能干扰的非打印控制字符
        // 这可以清理来自Telnet客户端的一些特殊控制序列
        $data = preg_replace('/[\x00-\x1F\x7F]/', '', $data);

        if (empty($data)) {
            $connection->send("ERROR: 空命令\r\n");
            return;
        }

        // 特殊处理退出命令
        if (in_array(strtolower($data), ['quit', 'exit', 'bye'])) {
            $connection->send("再见!\r\n");
            $connection->close();
            return;
        }

        // 路由匹配和执行
        $routeInfo = $this->router->match($data);
        $params = $routeInfo['params'] ?? '';
        $result = $this->router->dispatch($routeInfo, $params, $connection);

        $connection->send($result . "\r\n");
    }

    public function onClose(TcpConnection $connection): void
    {
        // 连接关闭清理，可记录日志等
    }

    public function onError(TcpConnection $connection, $code, $msg): void
    {
        echo "连接错误: {$code} - {$msg}\n";
    }

    /**
     * 获取路由器实例
     */
    public function getRouter(): Router
    {
        return $this->router;
    }

    /**
     * 注册新命令
     */
    public function registerCommand(string $command, string $handler, string $description = ''): self
    {
        $this->router->register($command, $handler, $description);
        return $this;
    }

    /**
     * 运行服务器
     */
    public function run(): void
    {
        Worker::runAll();
    }
}